<?php

namespace app\index\service;

use app\common\model\Trade;
use app\common\model\Transfer;
use app\common\service\TransfersServer;
use app\index\dao\TradeDao;
use app\index\model\UM as UM;
use app\index\service\payments\AccountPaymentService;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Request;

/**
 * Class BalanceRechargeService
 * @package app\index\service
 */
class TradeBalanceRechargeService implements TradableInterface, TransferableInterface
{
    // dao
    private TradeDao $tradeDao;

    public function __construct(TradeDao $tradeDao)
    {
        $this->tradeDao = $tradeDao;
    }

    /**
     * 新增
     * @param UM $user
     * @param array $params
     * @return  \app\common\model\Trade
     */
    public function add(UM $user, array $params): Trade
    {
        // 补齐参数，创建Trade
        $tradeType = TRADE_BALANCE_RECHARGE;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        $recharge_balance = $params['recharge_balance'] ?? null;
        if (!is_numeric($recharge_balance)) {
            throw new ValidateException('请输入正确的充值金额');
        }
        $recharge_balance = round($recharge_balance, 2);
        if ($recharge_balance <= 0) {
            throw new ValidateException('充值金额应该大于0元');
        }

        // 检查用户的余额账户是否可用
        if (!$this->getAccountPaymentService()->isEnableTransfer($user->id)) {
            throw new ValidateException('您的余额账户暂时不可用，请联系管理员');
        }

        $describe = $tradeConfig['name'] . $recharge_balance . '元';

        // 暂时没说优惠卷
        $showMoney = $recharge_balance;
        $totalMoney = $recharge_balance;
        $payMoney = $totalMoney;

        if($payMoney < 0.01){
            throw new ValidateException('订单价格应该大于0');
        }

        $tradeParams = [
            'memberId' => $user->id,
            'orderNoPre' => 'BR',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'recharge_balance' => $recharge_balance,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => Trade::NOTSETTLE,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
            'attach' => [
                'attach' => '',
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建时间
        event('TradeCreated', $record);

        return $record;
    }

    // 完成订单
    public function completionTrade(Trade $trade)
    {
        // 购买服务成功

        // 设置服务开始和完成时间
        $time = time();
        $trade->startTime = $time;
        $trade->save();

        // 直接插入一条转账申请
        $this->createTransfer($trade);

        // 触发订单完成事件
        event('TradeEnded', $trade);

    }

    // 完成退款
    public function completionRefundTrade(Trade $trade)
    {
        throw new ValidateException('充值订单不能退款');

        return;
    }

    public function canceledTrade(Trade $trade)
    {
        return;
    }

    // 完成转账后
    public function completionTransfer(Transfer $transfer): void
    {
        // 充值转账完成后，没有后续逻辑了，但还是给个空方法，方便回调使用
        return;
    }

    /**
     * 创建转账申请
     * @param Trade $trade
     * @return void
     */
    private function createTransfer(Trade $trade)
    {
        // 插入转账申请

        $transferType = TRANSFER_BALANCE_RECHARGE;
        $payMethod = PAYMENT_ACCOUNT;
        $memberId = $trade->memberId;
        $accountNumber = $trade->memberId;
        $describe = $trade->describe;
        $totalMoney = $trade->recharge_balance;
        $append = [
            'tradeId' => $trade->id
        ];
        $this->getTransfersServer()->pushTransferToMember($transferType, $memberId, $payMethod, $accountNumber, $totalMoney, $describe, $append);
    }

    private function getAccountPaymentService(): AccountPaymentService
    {
        return app(AccountPaymentService::class);
    }

    private function getTransfersServer(): TransfersServer
    {
        return app(TransfersServer::class);
    }
}
